home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************************************
- *
- *
- * MacZoop - "the framework for the rest of us"
- *
- *
- *
- * ZClassRegistry.cpp -- registry of classes used for persistent objects
- *
- *
- *
- *
- *
- * © 1998, Graham Cox
- *
- *
- *
- *
- *************************************************************************************************/
-
- #include "ZClassRegistry.h"
- #include "ZStream.h"
- #include "ZDefines.h"
- #include "ZErrors.h"
-
- ZClassRegistry::ZClassRegistry()
- : ZArray( sizeof( Object_Info ))
- {
- classID = 'zreg';
- }
-
-
- ZClassRegistry::~ZClassRegistry()
- {
- }
-
-
- /*--------------------------------*** REGISTERCLASS ***-------------------------------*/
- /*
- register a class to allow it to be instantiated from stream
- ----------------------------------------------------------------------------------------*/
-
- void ZClassRegistry::RegisterClass( OSType aType, ConstructorFunction aFunc, Str255 aName )
- {
- Object_Info oi;
-
- if ( FindClass( aType ) == 0 )
- {
- oi.classid = aType;
- oi.newfunc = aFunc;
- CopyPStringTrunc( aName, oi.classname, 31 );
- AppendItem( &oi );
- }
- }
-
-
- /*-------------------------------*** GETNAMEOFCLASS ***-------------------------------*/
- /*
- return name of class given its ID.
- ----------------------------------------------------------------------------------------*/
-
- void ZClassRegistry::GetNameOfClass( OSType aType, Str31 aName )
- {
- Object_Info oi;
- long index = FindClass( aType );
-
- if ( index > 0 )
- {
- GetArrayItem( &oi, index );
- CopyPString( oi.classname, aName );
- }
- else
- FailOSErr( kClassTypeUnknownErr );
- }
-
-
- /*------------------------------*** INSTANTIATECLASS ***------------------------------*/
- /*
- create a new object with the given class ID.
- ----------------------------------------------------------------------------------------*/
-
- ZObject* ZClassRegistry::InstantiateClass( OSType aType )
- {
- ZObject* obj = NULL;
- Object_Info oi;
- long index;
-
- index = FindClass( aType );
-
- if ( index > 0 )
- {
- GetArrayItem( &oi, index );
-
- if ( oi.newfunc == NULL )
- FailOSErr( kBadConstructorFuncErr );
-
- obj = (*oi.newfunc)();
- }
- else
- FailOSErr( kClassTypeUnknownErr );
-
- return obj;
- }
-
-
- /*------------------------------*** INSTANTIATECLASS ***------------------------------*/
- /*
- create a new object with the given class name.
- ----------------------------------------------------------------------------------------*/
-
- ZObject* ZClassRegistry::InstantiateClass( Str31 aName )
- {
- ZObject* obj = NULL;
- Object_Info oi;
- long index;
-
- index = FindClass( aName );
-
- if ( index > 0 )
- {
- GetArrayItem( &oi, index );
-
- if ( oi.newfunc == NULL )
- FailOSErr( kBadConstructorFuncErr );
-
- obj = (*oi.newfunc)();
- }
- else
- FailOSErr( kClassNameUnknownErr );
-
- return obj;
- }
-
-
- /*---------------------------------*** FINDCLASS ***----------------------------------*/
- /*
- return index of class with given ID in registry (internal method)
- ----------------------------------------------------------------------------------------*/
-
- long ZClassRegistry::FindClass( OSType aType )
- {
- Object_Info oi;
- long i;
-
- for( i = 1; i <= CountItems(); i++ )
- {
- GetArrayItem( &oi, i );
-
- if ( oi.classid == aType )
- return i;
- }
-
- return 0;
- }
-
-
- /*---------------------------------*** FINDCLASS ***----------------------------------*/
-
- long ZClassRegistry::FindClass( Str31 aName )
- {
- Object_Info oi;
- long i;
-
- for( i = 1; i <= CountItems(); i++ )
- {
- GetArrayItem( &oi, i );
-
- if ( EqualString( oi.classname, aName, FALSE, TRUE ))
- return i;
- }
-
- return 0;
- }
-
-
- #pragma mark -
-
-
- /*---------------------------*** INSTANTIATEFROMSTREAM ***----------------------------*/
- /*
- create a new object from the stream- normally this is called as necessary from the stream
- itself when an object is encountered.
- ----------------------------------------------------------------------------------------*/
-
- ZObject* ZClassRegistry::InstantiateFromStream( ZStream* aStream )
- {
- ZObject* root = NULL;
- OSType rootClassID;
-
- FailNILParam( aStream );
-
- // class ID must be next data in stream
-
- aStream->ReadLong((long*) &rootClassID );
- aStream->Skip( sizeof( long )); // ignore instance ID stored in stream
-
- // instantiate this class:
-
- root = InstantiateClass( rootClassID );
-
- // read the rest of the object's data (and other objects if necessary) into object
-
- root->ReadFromStream( aStream );
-
- return root;
- }
-